package org.springblade.modules.repair.controller;

import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.aliyun.oss.ServiceException;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springblade.common.utils.CommonUtil;
import org.springblade.core.log.annotation.ApiLog;
import org.springblade.core.mp.base.BaseEntity;
import org.springblade.core.redis.cache.BladeRedis;
import org.springblade.core.secure.utils.AuthUtil;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.utils.Func;
import org.springblade.core.tool.utils.WebUtil;
import org.springblade.modules.repair.dto.UserTrajectoryDTO;
import org.springblade.modules.repair.entity.MaintainPlanContent;
import org.springblade.modules.repair.enums.BuildingCacheEnum;
import org.springblade.modules.repair.enums.UserTrajectoryEnum;
import org.springblade.modules.repair.service.IBuildingService;
import org.springblade.modules.repair.service.IMaintainPlanContentService;
import org.springblade.modules.repair.vo.BuildingRedisVO;
import org.springblade.modules.system.entity.User;
import org.springblade.modules.system.service.IUserService;
import org.springblade.modules.system.service.IUserTrajectoryService;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * @author: Sharry
 * @createTime: 2023/4/26 15:35
 * @version: Version-1.0
 */
@Slf4j
@RestController
@RequestMapping("/trajectory")
@AllArgsConstructor
@Api(tags = "人员轨迹接口",value = "/trajectory")
public class UserTrajectoryController {

	private final IUserTrajectoryService uts;

	private final IBuildingService buildingService;

	private final BladeRedis bladeRedis;

	private final IUserService userService;

	private final IMaintainPlanContentService maintainPlanContentService;

	/**
	 * 记录人员轨迹
	 * @param userTrajectoryDTO 人员轨迹
	 * @return 是否记录成功
	 */
	@ApiLog("用户-上传用户经纬度")
	@PostMapping("/record")
	@ApiOperation("记录人员轨迹")
	@ApiOperationSupport(order = 10)
	public R<Boolean> record(@RequestBody UserTrajectoryDTO userTrajectoryDTO){
		userTrajectoryDTO.setFromType(CommonUtil.getRequestFromTypeByUA(WebUtil.getRequest().getHeader(WebUtil.USER_AGENT_HEADER)));
		// 手动传入租户id
		userTrajectoryDTO.setTenantId(AuthUtil.getTenantId());
		// 0. 必要的参数进行判断
		if(Func.isEmpty(userTrajectoryDTO.getUserId())){
			userTrajectoryDTO.setUserId(AuthUtil.getUserId());
		}
		// 当坐标为空
		if (Func.isNull(userTrajectoryDTO.getLongitude()) || Func.isNull(userTrajectoryDTO.getLatitude())) {
			throw new ServiceException("业务异常，用户经纬度坐标必须传入！");
		}
		// 当用户操作类型为空
		if (Func.isNull(userTrajectoryDTO.getOperation())) {
			userTrajectoryDTO.setOperation(UserTrajectoryEnum.OPERATION_NO_OPERATE.getValue());
		}
		// 当工单 id 不为空
		Long planId = userTrajectoryDTO.getPlanId();
		if (!Func.isNull(planId)) {
			MaintainPlanContent planById = maintainPlanContentService.getById(planId);
			if(Func.isNull(planById)){
				throw new ServiceException("业务异常，工单已删除或不存在！");
			}
			Integer typeStatus = planById.getTypeStatus();
			userTrajectoryDTO.setTypeStatus(typeStatus);
		}

		// 获取 用户真名,机构冗余数据 已交给查询时处理
		User user = userService.getOne(new LambdaQueryWrapper<User>().eq(BaseEntity::getId, userTrajectoryDTO.getUserId()));
		if (Func.isNull(user)) {
			throw new ServiceException("业务异常，该用户不存在！");
		}
		String realName = user.getRealName();
		userTrajectoryDTO.setRealName(realName);
		uts.record(userTrajectoryDTO);
		return R.data(Boolean.TRUE);
	}

	/**
	 * 添加项目列表缓存,预留接口
	 */
	@GetMapping("/cache")
	@ApiOperation("添加项目列表缓存")
	@ApiOperationSupport(order = 11)
	public R<Object> test(){
		// 组合 key ： 前缀 + 租户id
		String prefix = BuildingCacheEnum.BUILDING_REDIS_LIST.getKey();
		String tenantId = AuthUtil.getTenantId();
		String key = prefix + tenantId;
		// 获取目标对象列表
		List<BuildingRedisVO> buildingList = buildingService.listForVO();

		bladeRedis.del(key);
		// 执行
		buildingList.forEach(b -> bladeRedis.lPush(key,JSON.toJSONString(b)));
		Object[] redisBuildings = bladeRedis.lRange(key, 0, -1).toArray();
		return R.data(redisBuildings);
	}



}
